package com.zyx.concurrentdemo.c02basic.util;

import org.openjdk.jol.vm.VM;
import org.openjdk.jol.vm.VirtualMachine;

import java.io.PrintWriter;
import java.io.StringWriter;

/**
 * @author Yaxi.Zhang
 * @see org.openjdk.jol.info.ClassLayout
 * @since 2021/10/14 13:15
 * desc: simplify print the header of a object
 */
public class HeaderPrint {

    public static String printHeader(Object instance) {

        StringWriter sw = new StringWriter();
        PrintWriter pw = new PrintWriter(sw);

        if (instance != null) {
            VirtualMachine vm = VM.current();
            pw.printf("( ");
            for (long off = 4; off >= 0; off -= 4) {
                int word = vm.getInt(instance, off);
                pw.printf("%s",
                        toBinary((word >> 24) & 0xFF) + " " +
                                toBinary((word >> 16) & 0xFF) + " " +
                                toBinary((word >> 8) & 0xFF) + " " +
                                toBinary((word) & 0xFF) + " "
                );
            }
        } else {
            pw.printf("object header N/A");
        }
        pw.printf(")");

        pw.close();

        return sw.toString();
    }

    // very ineffective, so what?
    public static String toBinary(int x) {
        String s = Integer.toBinaryString(x);
        int deficit = 8 - s.length();
        for (int c = 0; c < deficit; c++) {
            s = "0" + s;
        }
        return s;
    }

    // very ineffective, so what?
    public static String toHex(int x) {
        String s = Integer.toHexString(x);
        int deficit = 2 - s.length();
        for (int c = 0; c < deficit; c++) {
            s = "0" + s;
        }
        return s;
    }

}
